#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <fstream>
#include <cassert>
using namespace std;
#define forn(i,n) for(int i=0;i<int(n);++i)
#define dforn(i,n) for(int i=(n)-1;i>=0;--i)
#define forsn(i,s,n) for(int i=s;i<int(n);++i)
#define forall(it,X) for(typeof(X.begin()) it = X.begin(); it != X.end(); ++it)
#define PI (acos(0.0)*2.0)

typedef vector< vector<double> > Mat;
typedef pair<double,double> pd;

Mat a;
int n,m;
double sigma;
int rnd(int n) { return rand()%n; }
double rnd01() { return double(rand()+1)/double(RAND_MAX); }
double normal01() {
	double a=rnd01(),b=rnd01();
	return sqrt(-2.0*log(a))*cos(2.0*PI*b);
}
double normal(double m, double sig) {
	return normal01()*sig+m;
}

int id(int i, int j) {return i*n+j;}

double off(double i1, double i2, double j1, double j2) {
	if (i1*i2>0.0) return -2.0;
	double dj=j2-j1;
	double ri=-i1/i2;
	double a=dj*ri/(ri+1.0);
	double jo=j1+a;
	if (abs(i2)<1e-7) jo=j2;
	//cout << i1 << " " << i2 << " " << j1 << " " << j2 << "=>" << jo << endl;
	if (jo>=0 && jo<=1.0) return jo;
	return -2.0;
}

pd point(double o, int c) {
	switch (c) {
		case 0: return pd(0,o);
		case 1: return pd(1,o);
		case 2: return pd(o,0);
		case 3: return pd(o,1);
	}
}

double sqr(double x) { return x*x; }
double dist(pd p, pd q) {
	return sqrt(sqr(p.first-q.first)+sqr(p.second-q.second));
}

void tirar(vector<double>& r, double ii1, double ii2, double jj1, double jj2) {
	r[n*n]=normal(0.0,sigma); //noise
    forn(i,n)forn(j,n) {
    	double& rr=r[id(i,j)];
    	double i1=ii1-i,i2=ii2-i,j1=jj1-j,j2=jj2-j;
    	double os[4]={
    		off(i1,i2,j1,j2),
    		off(i1-1,i2-1,j1,j2),
    		off(j1,j2,i1,i2),
    		off(j1-1,j2-1,i1,i2)};
    		//cout << ii1 << " " << ii2 << " " << jj1 << " " << jj2 << endl;
    		//cout << "  " << i << " " << j << endl;
    		//cout << "    "; forn(k,4) cout << " " << os[k]; cout << endl << "  ";
        forn(oi,4)if (os[oi]>=-1.0)forn(oj,oi)if(os[oj]>=-1.0) {
        	pd p=point(os[oi],oi),
        	   q=point(os[oj],oj);
        	   //cout << p.first << "," << p.second << "-" << q.first << "," << q.second << "  ";
        	rr=max(rr,dist(p,q));
        } 
        //cout << i << " " << j << " => " << rr << endl;
        r[n*n]+=rr/a[i][j];
    }
}

int main() {
    string fileName = "input.txt",outFileName="output.txt",matFileName;
    bool verbose=false;
    ifstream in(fileName.c_str());
    ofstream out(outFileName.c_str());
    int seed;
    in >> n >> m >> seed >> sigma;
    srand(seed);
    a=Mat(n, vector<double>(n));    
    Mat r(m, vector<double>(n*n+1));
    forn(i,n)forn(j,n) in >> a[i][j];
    double i1,i2,j1,j2;
    forn(i,m) {
        in >> i1 >> j1 >> i2 >> j2;
        //do not use horizontal or vertical rays, they cause undefinition!
        assert(0<=i1 && 0<=i2 && i1!=i2 && i1<=n && i2<=n);
        assert(0<=j1 && 0<=j2 && j1!=j2 && j1<=n && j2<=n);
        tirar(r[i],i1,i2,j1,j2);
        if (verbose) {
			cout << "rayo " << i << endl;
			forn(ii,n){
				forn(jj,n) cout << (r[i][id(ii,jj)]>=1e-7?'X':' '); 
				cout << endl;
			}
        }
    }
    out << n << " " << m << endl;
    forn(i,m) {
        forn(j,n*n+1) {
        	out.precision(20);
        	out << (j?" ":"") << r[i][j]; 
        }
        out << endl;
    }
    return 0;
}
